import time
import string
import random
import requests
from threading import Thread
from concurrent.futures import ThreadPoolExecutor


class TaskRequest:
    BASE_URL = 'http://192.168.1.96:8000/app01/index/'

    @staticmethod
    def _input_task_info():
        task_name = input('请输入任务名称:')
        task_desc = input('请输入任务描述:')
        return task_name, task_desc

    def _create_task_info(self, task_name=None, task_desc=None):
        if not all([task_name, task_desc]):
            task_name, task_desc = self._input_task_info()
        task_time = time.strftime('%Y-%m-%d %X', time.localtime())
        data = {
            'task_name': task_name,
            'task_time': task_time,
            'task_desc': task_desc,
        }
        return data

    def add_task(self, task_name=None, task_desc=None):
        data = self._create_task_info(task_name, task_desc)
        response = requests.post(self.BASE_URL + 'add/', data=data)
        return response.json()

    def get_task_all(self):
        response = requests.get(self.BASE_URL + 'get/')
        # print(response.json())
        return response.json()

    def get_task_one(self, tid=None):
        if not tid:
            tid = input('请输入查询的任务id').strip()
        response = requests.get(self.BASE_URL + 'get/' + f"{tid}/")
        # print(response.json())
        return response.json()

    def edit_task(self, tid=None):
        if not tid:
            tid = input('请输入修改的任务id:').strip()
        data = self._create_task_info()
        response = requests.post(self.BASE_URL + 'edit/' + f"{tid}/", data=data)
        # print(response.json())
        return response.json()

    def delete_task(self, tid=None):
        if not tid:
            tid = input('请输入删除的任务id:').strip()
        response = requests.get(self.BASE_URL + 'delete/' + f"{tid}/")
        # print(response.json())
        return response.json()

    @staticmethod
    def _create_random_string():
        txt = string.ascii_letters + string.digits
        # print(''.join(random.choices(txt, k=5)))
        return ''.join(random.choices(txt, k=5))

    def add_task_with_thread(self, num: int = 0):
        if not num:
            num = input('请输入创建次数: ').strip()
            if not num.isdigit():
                return "请输入数字"
            num = int(num)
        t_list = [Thread(target=self.add_task,
                         kwargs={'task_name': self._create_random_string(), 'task_desc': self._create_random_string()})
                  for i in range(num)]
        # 跑的次数太多，django会拒绝  # Max retries exceeded with url
        [t.start() for t in t_list]
        [t.join() for t in t_list]
        return f"使用多线程添加任务成功 {num}"

    def add_task_with_threadPool(self):
        pool = ThreadPoolExecutor(10)
        with pool:
            for i in range(1000):
                pool.submit(self.add_task, task_name=self._create_random_string(),
                            task_desc=self._create_random_string())
        return f"使用多线程添加任务成功"

    def main(self):
        menu = {
            '1': ('添加任务', self.add_task),
            '2': ('查询所有任务', self.get_task_all),
            '3': ('查询单个任务', self.get_task_one),
            '4': ('修改任务', self.edit_task),
            '5': ('删除任务', self.delete_task),
            # '6': ('使用多线程添加任务', self.add_task_with_thread),
            '6': ('使用多线程添加任务', self.add_task_with_threadPool),
        }
        while True:
            print('Task Assign'.center(50, '='))
            for k, v in menu.items():
                print(f"【{k}】: {v[0]}")
            select_func = input('请输入功能id: ').strip()
            if select_func.lower() == 'q':
                break
            if select_func not in menu:
                print("功能id不存在")
                continue
            else:
                print(menu[select_func][1]())
        print('系统已退出')


if __name__ == '__main__':
    t = TaskRequest()
    # for i in range(24, 26):
    #     t.add_task(f"task-{i}", f"task-{i}")
    # t.get_task_all()
    # t.get_task_one(100)
    # t.edit_task()
    # t.delete_task()
    # t.add_task_with_thread(65)
    t.main()
